﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFMINERP.DAL;
using WCFMINERP.COM;
using WCFMINERP.MODEL;

namespace WCFMINERP.BLL.Analyse
{
    public class BillBLL
    {
        public static decimal GetOrderPrice(Shop curShop, orderInfo oi, newSampleYPDBEntities db, Bill_Detail bd)
        {
            decimal orderInfoPrice = 0;//此单总金额

            List<Bill_Detail_Detail> bddList = new List<Bill_Detail_Detail>(); ;

            #region 新的计算产品价格

            #region 加载数据库
            if (!oi.Tb_ProductReference.IsLoaded)
            {
                oi.Tb_ProductReference.Load();
            }
            if (!oi.Tb_Product.Tb_PorductCategoryReference.IsLoaded)
            {
                oi.Tb_Product.Tb_PorductCategoryReference.Load();
            }
            if (!oi.photoInfo.IsLoaded)
            {
                oi.photoInfo.Load();
            }


            if (!curShop.Shop_Paper_Price.IsLoaded)
            {
                curShop.Shop_Paper_Price.Load();
            }
            if (!curShop.Shop_Product_Price.IsLoaded)
            {
                curShop.Shop_Product_Price.Load();
            }
            if (!curShop.Shop_CommonChargeItem_Price.IsLoaded)
            {
                curShop.Shop_CommonChargeItem_Price.Load();
            }

            #endregion

            Shop_Product_Price spp = curShop.Shop_Product_Price.FirstOrDefault(sp => sp.ProductId == oi.Tb_Product.ProuctId);
            if (!spp.tb_CostTypeReference.IsLoaded)
            {
                spp.tb_CostTypeReference.Load();
            }

            decimal UnitPrice = 0.0m;//单价
            double Num = 0.0;//数量，也包含面积

            #region 价格明细---第二层，即产品里面的名细，如规格，单价等

            switch (spp.tb_CostType.CostTypeId)
            {
                case 1: //按单价计价     

                    GetUnitAndAppendPrice(ref orderInfoPrice, oi, spp, ref UnitPrice, ref Num, bddList);
                    break;
                case 2:  //按平米计价,就要按此定单下的照片的规格分类
                case 6: //超常规直出，即超宽超长类直出              
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList); break;
                case 3://组合计价方式（即平米计价+产品单价）
                    //面积
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList);
                    //产品制作费
                    GetUnitAndAppendPrice(ref orderInfoPrice, oi, spp, ref UnitPrice, ref Num, bddList);

                    break;
                case 4://按照片张数计价
                    #region 按照片张数计价
                    var onePi = oi.photoInfo.FirstOrDefault();
                    if (spp == null)
                    {
                        UnitPrice = 0;
                    }
                    else
                    {
                        UnitPrice = spp.SinglePrice;
                    }
                    Num = oi.photoInfo.Sum(p => (int)p.TotalNum) * oi.productNum;

                    double countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;//外部返单不算钱
                    orderInfoPrice += Convert.ToDecimal(countT);

                    bddList.Add(new Bill_Detail_Detail()
                    {
                        Area = 0,
                        Count = countT,//外部返单不算钱
                        Num = (int)Num,
                        //Spec = onePi.Width.ToString("0.0") + "*" + onePi.Height.ToString("0.0") + "(" + (onePi.Width * 2.54).ToString("0.0") + "*" + (onePi.Height * 2.54).ToString("0.0") + ")",
                        Spec = oi.Tb_Product.ProductName,
                        DetailName = "单片输出",
                        Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                        UnitPrice = (double)UnitPrice
                    });
                    break;
                    #endregion
                case 5://淋膜压痕计类按面积收费的产品价
                    #region
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList);
                    // GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList, oi.Tb_Product.ProductName);
                    break;
                    #endregion
                case 7://淋膜压痕计类按面积收费的产品价

                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList);
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList, spp);

                    break;
                default:
                    break;
            }

            #region //再计费其它的收费项目的钱
            if (!oi.CommonChargeItem.IsLoaded)
            {
                oi.CommonChargeItem.Load();
            }

            foreach (var charItem in oi.CommonChargeItem.ToList())
            {
                double countT;
                var scp = curShop.Shop_CommonChargeItem_Price.ToList().FirstOrDefault(s => s.CommonChargeItemId == charItem.CommonChargeItemId);
                if (scp == null)
                {
                    continue;
                }
                if (!scp.CommonChargeItemReference.IsLoaded)
                {
                    scp.CommonChargeItemReference.Load();
                }
                switch (scp.CostTypeId)
                {
                    case 1: //按单价计价
                        #region
                        Num = oi.productNum;
                        UnitPrice = scp.UnitPrice;

                        countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;

                        orderInfoPrice += Convert.ToDecimal(countT);

                        bddList.Add(new Bill_Detail_Detail()
                        {
                            Area = 0,
                            Count = countT,
                            Num = (int)Num,
                            DetailName = scp.CommonChargeItem.ItemName,
                            Spec = scp.CommonChargeItem.ItemName,
                            Type = scp.CommonChargeItem.ItemName.Contains("设计") ? (int)Bill_Detail_Detail_Type.Design : (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                            UnitPrice = (double)UnitPrice
                        });
                        #endregion
                        break;
                    case 2:  //按平米计价,就要按此定单下的照片的规格分类
                        #region
                        UnitPrice = scp.AreaPrice;
                        Num = oi.photoInfo.Sum(pi => pi.Width * pi.Height * 2.54 * 2.54 / 10000 * (int)pi.TotalNum) * oi.productNum;

                        countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;

                        orderInfoPrice += Convert.ToDecimal(countT);

                        bddList.Add(new Bill_Detail_Detail()
                        {
                            Area = Num,
                            Count = countT,
                            Num = 0,
                            DetailName = scp.CommonChargeItem.ItemName,
                            Spec = scp.CommonChargeItem.ItemName,
                            Type = scp.CommonChargeItem.ItemName.Contains("设计") ? (int)Bill_Detail_Detail_Type.Design : (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                            UnitPrice = (double)UnitPrice
                        });
                        #endregion
                        break;
                    case 4://按照片张数计价,包括单张和跨页的计价方法
                        #region
                        if (scp.CommonChargeItem.ItemName == "单张设计")
                        {
                            Num = oi.SinglePageNum * oi.productNum;
                        }
                        else if (scp.CommonChargeItem.ItemName == "跨页设计")
                        {
                            Num = oi.MultiPageNum * oi.productNum;
                        }
                        else if (scp.CommonChargeItem.ItemName.Contains("设计"))//如果是设计就只选导入时的张数
                        {
                            Num = oi.photoInfo.GroupBy(p => p.picPath).Count();//也不管份数
                            //DesignCommint dm= db.DesignCommint.FirstOrDefault(p=>p.orderproductid==oi.OrderProductId);
                            //if (dm == null)
                            //{
                            //    Num = oi.photoInfo.GroupBy(p => p.picPath).Count();
                            //}
                        }
                        else
                        {
                            Num = oi.photoInfo.Sum(p => (int)p.TotalNum) * oi.productNum;
                        }

                        UnitPrice = scp.SinglePrice;
                        //Num = oi.photoInfo.Sum(p => (int)p.TotalNum) * oi.productNum;

                        countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;

                        orderInfoPrice += Convert.ToDecimal(countT);

                        bddList.Add(new Bill_Detail_Detail()
                        {
                            Area = 0,
                            Count = countT,
                            Num = (int)Num,
                            DetailName = scp.CommonChargeItem.ItemName,
                            Spec = scp.CommonChargeItem.ItemName,
                            Type = scp.CommonChargeItem.ItemName.Contains("设计") ? (int)Bill_Detail_Detail_Type.Design : (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                            UnitPrice = (double)UnitPrice
                        });
                        #endregion
                        break;
                    default:
                        break;
                }
            }

            #endregion

            foreach (var bdd in bddList)
            {
                bd.Bill_Detail_Detail.Add(bdd);
            }

            #endregion

            #endregion

            return Math.Round(orderInfoPrice, 4, MidpointRounding.ToEven);//保留二位
        }

        /// <summary>
        /// 公共的得到某产品的价格
        /// </summary>
        /// <returns></returns>
        public static decimal GetOrderPrice(int shopId, int orderProductId, newSampleYPDBEntities db, Bill_Detail bd)
        {
            var oi = db.orderInfo.Include("photoInfo").Include("paperType").FirstOrDefault(o => o.OrderProductId == orderProductId);
            var curShop = db.Shop.FirstOrDefault(s => s.ShopId == shopId);
            return GetOrderPrice(curShop, oi, db, bd);
        }

        public static decimal GetOrderPrice(Shop curShop, orderInfo oi, newSampleYPDBEntities db, Bill_Detail_Info bd)
        {
            decimal orderInfoPrice = 0;//此单总金额

            List<Bill_Detail_Detail_Info> bddList = new List<Bill_Detail_Detail_Info>();

            #region 新的计算产品价格

            #region 加载数据库
            if (!oi.Tb_ProductReference.IsLoaded)
            {
                oi.Tb_ProductReference.Load();
            }
            if (!oi.Tb_Product.Tb_PorductCategoryReference.IsLoaded)
            {
                oi.Tb_Product.Tb_PorductCategoryReference.Load();
            }
            if (!oi.photoInfo.IsLoaded)
            {
                oi.photoInfo.Load();
            }


            if (!curShop.Shop_Paper_Price.IsLoaded)
            {
                curShop.Shop_Paper_Price.Load();
            }
            if (!curShop.Shop_Product_Price.IsLoaded)
            {
                curShop.Shop_Product_Price.Load();
            }
            if (!curShop.Shop_CommonChargeItem_Price.IsLoaded)
            {
                curShop.Shop_CommonChargeItem_Price.Load();
            }

            #endregion

            Shop_Product_Price spp = curShop.Shop_Product_Price.FirstOrDefault(sp => sp.ProductId == oi.Tb_Product.ProuctId);
            if (!spp.tb_CostTypeReference.IsLoaded)
            {
                spp.tb_CostTypeReference.Load();
            }

            decimal UnitPrice = 0.0m;//单价
            double Num = 0.0;//数量，也包含面积

            #region 价格明细---第二层，即产品里面的名细，如规格，单价等

            switch (spp.tb_CostType.CostTypeId)
            {
                case 1: //按单价计价     

                    GetUnitAndAppendPrice(ref orderInfoPrice, oi, spp, ref UnitPrice, ref Num, bddList);
                    break;
                case 2:  //按平米计价,就要按此定单下的照片的规格分类
                case 6: //超常规直出，即超宽超长类直出              
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList); break;
                case 3://组合计价方式（即平米计价+产品单价）
                    //面积
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList);
                    //产品制作费
                    GetUnitAndAppendPrice(ref orderInfoPrice, oi, spp, ref UnitPrice, ref Num, bddList);

                    break;
                case 4://按照片张数计价
                    #region 按照片张数计价
                    var onePi = oi.photoInfo.FirstOrDefault();
                    if (spp == null)
                    {
                        UnitPrice = 0;
                    }
                    else
                    {
                        UnitPrice = spp.SinglePrice;
                    }
                    Num = oi.photoInfo.Sum(p => (int)p.TotalNum) * oi.productNum;

                    double countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;//外部返单不算钱
                    orderInfoPrice += Convert.ToDecimal(countT);

                    bddList.Add(new Bill_Detail_Detail_Info()
                    {
                        Area = 0,
                        Count = countT,//外部返单不算钱
                        Num = (int)Num,
                        //Spec = onePi.Width.ToString("0.0") + "*" + onePi.Height.ToString("0.0") + "(" + (onePi.Width * 2.54).ToString("0.0") + "*" + (onePi.Height * 2.54).ToString("0.0") + ")",
                        Spec = oi.Tb_Product.ProductName,
                        DetailName = "单片输出",
                        Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                        UnitPrice = (double)UnitPrice
                    });
                    break;
                    #endregion
                case 5://淋膜压痕计类按面积收费的产品价
                    #region
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList);
                    // GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList, oi.Tb_Product.ProductName);
                    break;
                    #endregion
                case 7://淋膜压痕计类按面积收费的产品价

                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList);
                    GetAreaPrice(ref orderInfoPrice, oi, curShop, ref UnitPrice, ref Num, bddList, spp);

                    break;
                default:
                    break;
            }

            #region //再计费其它的收费项目的钱
            if (!oi.CommonChargeItem.IsLoaded)
            {
                oi.CommonChargeItem.Load();
            }

            foreach (var charItem in oi.CommonChargeItem.ToList())
            {
                double countT;
                var scp = curShop.Shop_CommonChargeItem_Price.ToList().FirstOrDefault(s => s.CommonChargeItemId == charItem.CommonChargeItemId);
                if (scp == null)
                {
                    continue;
                }
                if (!scp.CommonChargeItemReference.IsLoaded)
                {
                    scp.CommonChargeItemReference.Load();
                }
                switch (scp.CostTypeId)
                {
                    case 1: //按单价计价
                        #region
                        Num = oi.productNum;
                        UnitPrice = scp.UnitPrice;

                        countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;

                        orderInfoPrice += Convert.ToDecimal(countT);

                        bddList.Add(new Bill_Detail_Detail_Info()
                        {
                            Area = 0,
                            Count = countT,
                            Num = (int)Num,
                            DetailName = scp.CommonChargeItem.ItemName,
                            Spec = scp.CommonChargeItem.ItemName,
                            Type = scp.CommonChargeItem.ItemName.Contains("设计") ? (int)Bill_Detail_Detail_Type.Design : (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                            UnitPrice = (double)UnitPrice
                        });
                        #endregion
                        break;
                    case 2:  //按平米计价,就要按此定单下的照片的规格分类
                        #region
                        UnitPrice = scp.AreaPrice;
                        Num = oi.photoInfo.Sum(pi => pi.Width * pi.Height * 2.54 * 2.54 / 10000 * (int)pi.TotalNum) * oi.productNum;

                        countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;

                        orderInfoPrice += Convert.ToDecimal(countT);

                        bddList.Add(new Bill_Detail_Detail_Info()
                        {
                            Area = Num,
                            Count = countT,
                            Num = 0,
                            DetailName = scp.CommonChargeItem.ItemName,
                            Spec = scp.CommonChargeItem.ItemName,
                            Type = scp.CommonChargeItem.ItemName.Contains("设计") ? (int)Bill_Detail_Detail_Type.Design : (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                            UnitPrice = (double)UnitPrice
                        });
                        #endregion
                        break;
                    case 4://按照片张数计价,包括单张和跨页的计价方法
                        #region
                        if (scp.CommonChargeItem.ItemName == "单张设计")
                        {
                            Num = oi.SinglePageNum * oi.productNum;
                        }
                        else if (scp.CommonChargeItem.ItemName == "跨页设计")
                        {
                            Num = oi.MultiPageNum * oi.productNum;
                        }
                        else if (scp.CommonChargeItem.ItemName.Contains("设计"))//如果是设计就只选导入时的张数
                        {
                            Num = oi.photoInfo.GroupBy(p => p.picPath).Count();//也不管份数
                            //DesignCommint dm= db.DesignCommint.FirstOrDefault(p=>p.orderproductid==oi.OrderProductId);
                            //if (dm == null)
                            //{
                            //    Num = oi.photoInfo.GroupBy(p => p.picPath).Count();
                            //}
                        }
                        else
                        {
                            Num = oi.photoInfo.Sum(p => (int)p.TotalNum) * oi.productNum;
                        }

                        UnitPrice = scp.SinglePrice;
                        //Num = oi.photoInfo.Sum(p => (int)p.TotalNum) * oi.productNum;

                        countT = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;

                        orderInfoPrice += Convert.ToDecimal(countT);

                        bddList.Add(new Bill_Detail_Detail_Info()
                        {
                            Area = 0,
                            Count = countT,
                            Num = (int)Num,
                            DetailName = scp.CommonChargeItem.ItemName,
                            Spec = scp.CommonChargeItem.ItemName,
                            Type = scp.CommonChargeItem.ItemName.Contains("设计") ? (int)Bill_Detail_Detail_Type.Design : (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                            UnitPrice = (double)UnitPrice
                        });
                        #endregion
                        break;
                    default:
                        break;
                }
            }

            #endregion

            foreach (var bdd in bddList)
            {
                bd.ListDetail_Detail.Add(bdd);
            }

            #endregion

            #endregion

            return Math.Round(orderInfoPrice, 4, MidpointRounding.ToEven);//保留二位
        }


        /// <summary>
        /// 开单成功后，更新此定单包的帐单信息
        /// </summary>
        /// <param name="orderBagId"></param>
        /// <returns>开单成功，开单不成功</returns>
        public static int UpdateBillInfo(int orderBagId)
        {
            int result = 0;

            if (orderBagId < 1)
            {
                return -1;//ID不正确
            }
            try
            {
                using (newSampleYPDBEntities DB = new newSampleYPDBEntities())
                {
                    Tb_OrderBag orderBag = DB.Tb_OrderBag.FirstOrDefault(ob => ob.OrderBagId == orderBagId);

                    if (orderBag == null)
                    {
                        return 0;//未找到此产品
                    }

                    #region 加载数据

                    if (!orderBag.orderInfo.IsLoaded)
                    {
                        orderBag.orderInfo.Load();
                    }
                    else
                    {
                        //DALBase.DataEntites.Refresh(System.Data.Objects.RefreshMode.StoreWins, orderBag.orderInfo);
                    }
                    if (!orderBag.ShopReference.IsLoaded)
                    {
                        orderBag.ShopReference.Load();
                    }
                    else
                    {
                        orderBag.ShopReference.Load(System.Data.Objects.MergeOption.OverwriteChanges);
                    }
                    if (!orderBag.Shop.Shop_Product_Price.IsLoaded)
                    {
                        orderBag.Shop.Shop_Product_Price.Load();
                    }

                    #endregion

                    foreach (var oi in orderBag.orderInfo)
                    {
                        decimal orderInfoPrice = 0;//此产品的真实价格
                        Bill_Detail temp = new Bill_Detail();
                        orderInfoPrice = GetOrderPrice(orderBag.Shop, oi, DB, temp);

                        oi.PrePriceCount = (decimal)orderInfoPrice;

                        if (orderBag.Shop.AccountControlTechId != 1)//不由开始来控制
                        {
                            if (oi.photoInfo.Count == 0)
                            {
                                oi.status = (int)OrderInfoStatus.Doing;
                            }
                            else
                            {
                                oi.status = (int)OrderInfoStatus.WaitPhotoMove;
                            }
                            result = 2;
                        }
                        else
                        {
                            CheckOrderCount(oi, orderBag.Shop, true, DB);
                        }
                    }
                    int intProductDoingNum = orderBag.orderInfo.Count(p => p.status == (int)OrderInfoStatus.Doing || p.status == (int)OrderInfoStatus.WaitPay);
                    int ingProduct = orderBag.orderInfo.Count;
                    if (ingProduct == intProductDoingNum)
                    {
                        orderBag.Status = (int)OrderBagStatus.Doing;
                    }
                    DB.SaveChanges();
                }
            }
            catch (Exception)
            {
                WriteLogForCheck.WriteLogFile("在调用DALBASE.SAVE()方法时出错");
                throw;
            }

            return result;//成功
        }

        public static void InsertAccountAlarmMsg(string msg, string remark, Shop shop, newSampleYPDBEntities dataBase, DateTime curTime)
        {
            List<AlarmReceiver> receiveMsgUserId = dataBase.AlarmReceiver.ToList();
            if (receiveMsgUserId.Count > 0)
            {
                foreach (var item in receiveMsgUserId)
                {
                    if (!item.usersReference.IsLoaded)
                    {
                        item.usersReference.Load();
                    }
                    dataBase.AddToAccountAlarmMsg(new AccountAlarmMsg() { Msg = msg, ReaderUid = item.users.userID, Status = (int)AccountAlarmStatus.UnReaded, Remark = remark, SenderUid = 0, Shop = shop, AlarmTime = curTime });
                }
            }
            else
            {
                //如果没有设置接收者的话就发送到USER表中第一个用户那里
                users fu = dataBase.users.FirstOrDefault();
                if (fu != null)
                {
                    dataBase.AddToAccountAlarmMsg(new AccountAlarmMsg() { Msg = msg, ReaderUid = fu.userID, Status = (int)AccountAlarmStatus.UnReaded, Remark = remark, SenderUid = 0, Shop = shop, AlarmTime = curTime });
                }
            }
        }


        /// <summary>
        /// 向财务报警表添加记录 
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="remark"></param>
        /// <param name="shop"></param>
        /// <param name="dataBase"></param>
        public static void InsertAccountAlarmMsg(string msg, string remark, Shop shop, newSampleYPDBEntities dataBase)
        {
            DateTime curTime = CommonMethodDAL.GetServerTime();
            InsertAccountAlarmMsg(msg, remark, shop, dataBase, curTime);
        }

        /// <summary>
        /// 进行财务审核，主要是审核到此刻该商户是否欠钱不能生产，然后发出相应的报警信息
        /// </summary>
        /// <param name="oi"></param>
        /// <param name="shop"></param>
        /// <param name="isStartOrder"></param>
        /// <param name="dataBase"></param>
        public static void CheckOrderCount(orderInfo oi, Shop shop, bool isStartOrder, newSampleYPDBEntities dataBase)
        {
            switch (shop.CheckOutType)
            {
                case 2://现结用户，检查有没有欠款，有欠款就审核
                    #region
                    if (shop.Balance >= 0)//无欠款
                    {
                        //开单成功，并更改OrderBalance

                        oi.status = (int)OrderInfoStatus.Doing;

                        //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                        shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                    }
                    else//有欠款
                    {

                        oi.status = (int)OrderInfoStatus.WaitPay;

                    }
                    break;
                    #endregion
                case 0://预付

                    #region

                    if (shop.Balance - shop.OrderBalance >= (oi.PrePriceCount == null ? 0 : oi.PrePriceCount))
                    {

                        oi.status = (int)OrderInfoStatus.Doing;

                        //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                        shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                    }
                    else//钱不够
                    {

                        oi.status = (int)OrderInfoStatus.WaitPay;
                    }
                    //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;



                    //检查是否需要提示
                    if (shop.Balance - shop.OrderBalance <= shop.AlarmLimit)
                    {
                        InsertAccountAlarmMsg("可开单余额小于:" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);
                    }
                    break;
                    #endregion
                case 1://信用额度

                    #region 信用额度
                    if (shop.CreditLimit - shop.OrderBalance + shop.Balance >= (oi.PrePriceCount == null ? 0 : oi.PrePriceCount))
                    {

                        oi.status = (int)OrderInfoStatus.Doing;

                        //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                        shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                    }
                    else
                    {

                        oi.status = (int)OrderInfoStatus.WaitPay;
                    }
                    //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;




                    if (shop.CreditLimit - shop.OrderBalance + shop.Balance <= shop.AlarmLimit)
                    {
                        InsertAccountAlarmMsg("开单余额小于:" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);
                    }

                    break;
                    #endregion

                case 3://结帐日期限制  
                    DateTime curTime = CommonMethodDAL.GetServerTime();//获取系统时间
                    TimeSpan days = curTime.Date.Subtract(new DateTime(curTime.Year, curTime.Month, (int)shop.OverDay + (int)shop.GraceDay));
                    if (days.Days >= 0 && days.Days <= shop.AlarmDays)
                    {
                        InsertAccountAlarmMsg("提醒:距结帐日还有:" + days.Days + "天", "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);
                    }
                    #region 结帐日
                    //每月5号结帐日，5天宽限,在每月的10号以后，就看本月以前
                    if (shop.OverDay + shop.GraceDay < curTime.Day)//10号以后
                    {
                        //检查本月以前是否有欠款
                        if (IsIndebtInLastMoth(shop.ShopId, dataBase))//上月已结清，可以继续下单
                        {

                            oi.status = (int)OrderInfoStatus.Doing;

                            //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                            shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                        }
                        else//未结清，不能下单
                        {
                            oi.status = (int)OrderInfoStatus.WaitPay;

                            //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;
                            InsertAccountAlarmMsg("上月有帐单未结清，不能下单" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);

                        }
                    }
                    else//1号到10号,就看的上个月以前是否结清
                    {
                        //检查上个月以前的有否欠款
                        //DateTime dateNow = CommonMethodDAL.GetServerTime();
                        //DateTime lastMonth=curTime.AddMonths(-1).f
                        DateTime lastMonth = Convert.ToDateTime(curTime.ToString("yyyy-MM-01")).AddMonths(-1);
                        int unCheck = (int)ShopBillStatus.UnCheckOut;

                        List<SHOP_Bill> listBill = dataBase.SHOP_Bill.Where(sb => sb.Shop.ShopId == shop.ShopId && sb.Status == unCheck && lastMonth > sb.CreateTime).ToList();
                        if (listBill.Count > 0)
                        {

                            oi.status = (int)OrderInfoStatus.WaitPay;

                            //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;
                            InsertAccountAlarmMsg("上上月有帐单未结清，不能下单" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);

                        }
                        else
                        {
                            //已结清可以下单

                            oi.status = (int)OrderInfoStatus.Doing;

                            //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                            shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                        }
                    }
                    break;
                    #endregion

                case 4://时间与信用额度同时控制

                    DateTime curTime1 = CommonMethodDAL.GetServerTime();//获取系统时间

                    //DateTime lastMonth = Convert.ToDateTime(curTime1.ToString("yyyy-MM-01")).AddMonths(-1);
                    TimeSpan days1 = curTime1.Subtract(new DateTime(curTime1.Year, curTime1.Month, (int)shop.OverDay + (int)shop.GraceDay));
                    if (days1.Days >= 0 && days1.Days <= shop.AlarmDays)
                    {
                        InsertAccountAlarmMsg("距结帐日还有:" + days1.Days + "天", "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);
                    }

                    #region 时间与信用额度同时控制
                    if (shop.CreditLimit + shop.OrderBalance - shop.OrderBalance >= (oi.PrePriceCount == null ? 0 : oi.PrePriceCount))//信用额度满足
                    {
                        //每月5号结帐日，5天宽限
                        if (shop.OverDay + shop.GraceDay < curTime1.Day)//10号以后
                        {
                            //检查本月以前是否有欠款
                            if (IsIndebtInLastMoth(shop.ShopId, dataBase))//上月已结清，可以继续下单
                            {

                                oi.status = (int)OrderInfoStatus.Doing;

                                //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                                shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                            }
                            else//未结清，不能下单
                            {

                                oi.status = (int)OrderInfoStatus.WaitPay;
                            }
                            //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;
                            InsertAccountAlarmMsg("上月有帐单未结清，不能下单" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);


                        }
                        else//1号到10号
                        {
                            //检查上个月以前的有否欠款
                            //DateTime dateNow = CommonMethodDAL.GetServerTime();
                            DateTime lastMonth = Convert.ToDateTime(curTime1.ToString("yyyy-MM-01")).AddMonths(-1);

                            //if (Shop_BillDAL.GetBillByShopIdAndStatus(shop.ShopId, ShopBillStatus.UnCheckOut, new DateTime(curTime1.Year, curTime1.Month - 1, 1)).Count > 0)
                            //DateTime lastMonth = Convert.ToDateTime(curTime.ToString("yyyy-MM-01")).AddMonths(-1);
                            int unCheck = (int)ShopBillStatus.UnCheckOut;

                            List<SHOP_Bill> listBill = dataBase.SHOP_Bill.Where(sb => sb.Shop.ShopId == shop.ShopId && sb.Status == unCheck && lastMonth > sb.CreateTime).ToList();
                            if (listBill.Count > 0)
                            {
                                //未结清不能下单

                                oi.status = (int)OrderInfoStatus.WaitPay;

                                //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;
                                InsertAccountAlarmMsg("上月有帐单未结清，不能下单" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);

                            }
                            else
                            {
                                //已结清可以下单

                                oi.status = (int)OrderInfoStatus.Doing;

                                //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPhotoMove : (int)OrderInfoStatus.Doing;
                                shop.OrderBalance += oi.PrePriceCount == null ? 0 : oi.PrePriceCount;
                            }
                        }
                    }
                    else
                    {

                        oi.status = (int)OrderInfoStatus.WaitPay;

                        //oi.status = isStartOrder ? (int)OrderInfoStatus.WaitPayAndWaitMovePhoto : (int)OrderInfoStatus.WaitPay;
                        InsertAccountAlarmMsg("上月有帐单未结清，不能下单" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);

                    }

                    if (shop.CreditLimit - shop.OrderBalance + shop.Balance <= shop.AlarmLimit)
                    {
                        InsertAccountAlarmMsg("开单余额小于:" + shop.AlarmLimit, "产品号：" + oi.OrderProductId + "产品预计金额：" + oi.PrePriceCount + "当前余额为：" + shop.Balance, shop, dataBase);
                    }

                    break;//信用额度
                    #endregion
                default:
                    // WriteLogForCheck.WriteLogFile("商户 " + shop.shopName + " 的结算类型不存在!");
                    break;
            }
            if (shop.ForceCheck)
            {
                oi.status = (int)OrderInfoStatus.AutoOrderWait;
            }
        }



        #region help methods



        /// <summary>
        /// 得到制作费以及附加页费用
        /// </summary>
        /// <param name="orderInfoPrice"></param>
        /// <param name="oi"></param>
        /// <param name="spp"></param>
        /// <param name="UnitPrice"></param>
        /// <param name="Num"></param>
        private static void GetUnitAndAppendPrice(ref decimal orderInfoPrice, orderInfo oi, Shop_Product_Price spp, ref decimal UnitPrice, ref double Num, List<Bill_Detail_Detail> bddList)
        {
            double count = 0;
            if (oi.Tb_Product.PageNum == -1)//这类产品就是指框、水晶一类，即同一个文件夹中有多张相同尺寸的照片都做同一样的框的情况 ，只收框的钱，没有附加页
            {
                if (spp == null)
                {
                    UnitPrice = 0;
                }
                else
                {
                    UnitPrice = spp.UnitPrice;
                }
                Num = oi.productNum * (oi.photoInfo.Count == 0 ? 1 : oi.photoInfo.Count);//份数

                count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;
                orderInfoPrice += Convert.ToDecimal(count);
                bddList.Add(new Bill_Detail_Detail()
                {
                    Area = 0,
                    Count = count,
                    DetailName = oi.Tb_Product.Tb_PorductCategory.ProductCategoryName,
                    Num = (int)Num,
                    Spec = oi.Tb_Product.ProductName + "(" + oi.Tb_Product.Width + "×" + oi.Tb_Product.Height + "英寸)",
                    Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                    UnitPrice = (double)UnitPrice
                });

                return;
            }
            #region 计算制作费的钱

            if (spp == null)
            {
                UnitPrice = 0;
            }
            else
            {
                UnitPrice = spp.UnitPrice;
            }
            Num = oi.productNum;//份数
            count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;
            orderInfoPrice += Convert.ToDecimal(count);
            bddList.Add(new Bill_Detail_Detail()
            {
                Area = 0,
                Count = count,
                DetailName = oi.Tb_Product.Tb_PorductCategory.ProductCategoryName,
                Num = (int)Num,
                Spec = oi.Tb_Product.ProductName + "(" + oi.Tb_Product.Width + "×" + oi.Tb_Product.Height + "英寸)",
                Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                UnitPrice = (double)UnitPrice
            });

            #endregion

            #region 计算附加页的钱

            Num = 0;

            //再计算附加页热的明细
            if (oi.photoInfo.Count > oi.Tb_Product.PageNum)//含照片
            {
                Num = (oi.photoInfo.Count - oi.Tb_Product.PageNum) * oi.productNum;// 多份的情况               
            }
            if (oi.photoInfo.Count == 0 && oi.PageNum > oi.Tb_Product.PageNum)//不含照片，即来片做相册
            {
                Num = (oi.PageNum - oi.Tb_Product.PageNum) * oi.productNum;// 多份的情况 
            }

            if (Num > 0)
            {
                if (spp == null)
                {
                    UnitPrice = 0;
                }
                else
                {
                    UnitPrice = spp.AppendPrice;//附加页的价格
                }


                decimal appendCount = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Convert.ToDecimal(Num * (double)spp.AppendPrice);
                orderInfoPrice += appendCount;
                bddList.Add(new Bill_Detail_Detail()
                {
                    Area = 0,
                    Count = (double)appendCount,
                    DetailName = "附加页",
                    Num = (int)Num,
                    Spec = oi.Tb_Product.ProductName + "(" + oi.Tb_Product.Width + "×" + oi.Tb_Product.Height + "英寸)",
                    Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                    UnitPrice = (double)UnitPrice
                });
            }
            #endregion
        }

        /// <summary>
        /// 得到制作费以及附加页费用
        /// </summary>
        /// <param name="orderInfoPrice"></param>
        /// <param name="oi"></param>
        /// <param name="spp"></param>
        /// <param name="UnitPrice"></param>
        /// <param name="Num"></param>
        private static void GetUnitAndAppendPrice(ref decimal orderInfoPrice, orderInfo oi, Shop_Product_Price spp, ref decimal UnitPrice, ref double Num, List<Bill_Detail_Detail_Info> bddList)
        {
            double count = 0;
            if (oi.Tb_Product.PageNum == -1)//这类产品就是指框、水晶一类，即同一个文件夹中有多张相同尺寸的照片都做同一样的框的情况 ，只收框的钱，没有附加页
            {
                if (spp == null)
                {
                    UnitPrice = 0;
                }
                else
                {
                    UnitPrice = spp.UnitPrice;
                }
                Num = oi.productNum * (oi.photoInfo.Count == 0 ? 1 : oi.photoInfo.Count);//份数

                count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;
                orderInfoPrice += Convert.ToDecimal(count);
                bddList.Add(new Bill_Detail_Detail_Info()
                {
                    Area = 0,
                    Count = count,
                    DetailName = oi.Tb_Product.Tb_PorductCategory.ProductCategoryName,
                    Num = (int)Num,
                    Spec = oi.Tb_Product.ProductName + "(" + oi.Tb_Product.Width + "×" + oi.Tb_Product.Height + "英寸)",
                    Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                    UnitPrice = (double)UnitPrice
                });

                return;
            }
            #region 计算制作费的钱

            if (spp == null)
            {
                UnitPrice = 0;
            }
            else
            {
                UnitPrice = spp.UnitPrice;
            }
            Num = oi.productNum;//份数
            count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Num * (double)UnitPrice;
            orderInfoPrice += Convert.ToDecimal(count);
            bddList.Add(new Bill_Detail_Detail_Info()
            {
                Area = 0,
                Count = count,
                DetailName = oi.Tb_Product.Tb_PorductCategory.ProductCategoryName,
                Num = (int)Num,
                Spec = oi.Tb_Product.ProductName + "(" + oi.Tb_Product.Width + "×" + oi.Tb_Product.Height + "英寸)",
                Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                UnitPrice = (double)UnitPrice
            });

            #endregion

            #region 计算附加页的钱

            Num = 0;

            //再计算附加页热的明细
            if (oi.photoInfo.Count > oi.Tb_Product.PageNum)//含照片
            {
                Num = (oi.photoInfo.Count - oi.Tb_Product.PageNum) * oi.productNum;// 多份的情况               
            }
            if (oi.photoInfo.Count == 0 && oi.PageNum > oi.Tb_Product.PageNum)//不含照片，即来片做相册
            {
                Num = (oi.PageNum - oi.Tb_Product.PageNum) * oi.productNum;// 多份的情况 
            }

            if (Num > 0)
            {
                if (spp == null)
                {
                    UnitPrice = 0;
                }
                else
                {
                    UnitPrice = spp.AppendPrice;//附加页的价格
                }


                decimal appendCount = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Convert.ToDecimal(Num * (double)spp.AppendPrice);
                orderInfoPrice += appendCount;
                bddList.Add(new Bill_Detail_Detail_Info()
                {
                    Area = 0,
                    Count = (double)appendCount,
                    DetailName = "附加页",
                    Num = (int)Num,
                    Spec = oi.Tb_Product.ProductName + "(" + oi.Tb_Product.Width + "×" + oi.Tb_Product.Height + "英寸)",
                    Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                    UnitPrice = (double)UnitPrice
                });
            }
            #endregion
        }

        /// <summary>
        /// 取得面积总费用
        /// </summary>
        /// <param name="orderInfoPrice"></param>
        /// <param name="oi"></param>
        /// <param name="curShop"></param>
        /// <param name="UnitPrice"></param>
        /// <param name="Num"></param>
        private static void GetAreaPrice(ref decimal orderInfoPrice, orderInfo oi, Shop curShop, ref decimal UnitPrice, ref double Num, List<Bill_Detail_Detail> bddList)
        {
            decimal superOutPaperPrice = -1;//超出尺寸的输出价格的加价是多少
            bool isSuperOut = false;//是否超出尺寸

            foreach (var p in oi.photoInfo)
            {
                if (!p.paperTypeReference.IsLoaded)
                {
                    p.paperTypeReference.Load();
                }
            }

            #region //这种情况主要针对开单计算预估价格时产品是设计类的情况
            if (oi.PageNum > 0 && oi.photoInfo.Count > 0 && oi.photoInfo.Count > oi.PageNum && (oi.ProductType == (int)OrderInfoProductType.NeedDesignProduct || oi.ProductType == (int)OrderInfoProductType.NeedDesignPrint))//这种情况主要针对开单计算预估价格时产品是设计类的情况
            {
                //如果是这种情况就用如下的方式
                double Area = 0, Count;
                photoInfo firstP = oi.photoInfo.FirstOrDefault();
                if (!firstP.paperTypeReference.IsLoaded)
                {
                    firstP.paperTypeReference.Load();
                }

                var shopPaperPrice = curShop.Shop_Paper_Price.FirstOrDefault(sp => sp.PaperTypeId == firstP.paperType.PaperTypeID);
                if (shopPaperPrice != null)
                {
                    UnitPrice = shopPaperPrice.UnitPrice;
                }
                else
                {
                    UnitPrice = 0;
                }
                Area = (oi.Width * oi.Height * 2.54 * 2.54) * oi.PageNum / 10000;//平方米
                Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Area * (double)UnitPrice;

                orderInfoPrice += Convert.ToDecimal(Count);


                bddList.Add(new Bill_Detail_Detail()
                {
                    Area = Area,
                    Count = Count,
                    DetailName = firstP.paperType.Name + "数码输出",
                    Num = (int)Num,
                    Spec = oi.Width.ToString() + "*" + oi.Height.ToString(),
                    Type = (int)Bill_Detail_Detail_Type.NeedStatArea,
                    UnitPrice = (double)UnitPrice
                });

                return;

            }
            #endregion

            foreach (var ps in oi.photoInfo.GroupBy(p => p.paperType))
            {
                var shopPaperPrice = curShop.Shop_Paper_Price.FirstOrDefault(sp => sp.PaperTypeId == ps.Key.PaperTypeID);


                #region new
                foreach (var pSize in GetSizeInfo(ps.ToList()))
                {

                    isSuperOut = false;

                    if (shopPaperPrice != null)
                    {
                        UnitPrice = shopPaperPrice.UnitPrice;
                    }
                    else
                    {
                        UnitPrice = 0;
                    }

                    if (pSize.Width > 30 && pSize.Height > 30)
                    {
                        //超了  
                        isSuperOut = true;
                    }
                    else if (pSize.Width <= 30 && pSize.Height > 49)
                    {
                        //超了
                        isSuperOut = true;
                    }
                    else if (pSize.Height <= 30 && pSize.Width > 49)
                    {
                        //超了
                        isSuperOut = true;
                    }

                    if (isSuperOut && superOutPaperPrice == -1)
                    {
                        //从SystemSetting表中获取加费的的价格
                        //superOutPaperPrice = SystemSettingDAL.GetSuperOutPaperPrice();
                    }

                    if (isSuperOut)
                    {
                        UnitPrice += superOutPaperPrice;
                    }


                    double Count;
                    Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : pSize.Areas * (double)UnitPrice;
                    orderInfoPrice += Convert.ToDecimal(Count);
                    bddList.Add(new Bill_Detail_Detail()
                    {
                        Area = Math.Round(pSize.Areas, 4),
                        Count = Count,
                        DetailName = ps.Key.Name + "数码输出",
                        Num = pSize.Num,
                        Spec = pSize.Spec,
                        Type = (int)Bill_Detail_Detail_Type.NeedStatArea,
                        UnitPrice = (double)UnitPrice
                    });
                }
                #endregion

            }
        }

        /// <summary>
        /// 取得面积总费用
        /// </summary>
        /// <param name="orderInfoPrice"></param>
        /// <param name="oi"></param>
        /// <param name="curShop"></param>
        /// <param name="UnitPrice"></param>
        /// <param name="Num"></param>
        private static void GetAreaPrice(ref decimal orderInfoPrice, orderInfo oi, Shop curShop, ref decimal UnitPrice, ref double Num, List<Bill_Detail_Detail_Info> bddList)
        {
            decimal superOutPaperPrice = -1;//超出尺寸的输出价格的加价是多少
            bool isSuperOut = false;//是否超出尺寸

            foreach (var p in oi.photoInfo)
            {
                if (!p.paperTypeReference.IsLoaded)
                {
                    p.paperTypeReference.Load();
                }
            }

            #region //这种情况主要针对开单计算预估价格时产品是设计类的情况
            if (oi.PageNum > 0 && oi.photoInfo.Count > 0 && oi.photoInfo.Count > oi.PageNum && (oi.ProductType == (int)OrderInfoProductType.NeedDesignProduct || oi.ProductType == (int)OrderInfoProductType.NeedDesignPrint))//这种情况主要针对开单计算预估价格时产品是设计类的情况
            {
                //如果是这种情况就用如下的方式
                double Area = 0, Count;
                photoInfo firstP = oi.photoInfo.FirstOrDefault();
                if (!firstP.paperTypeReference.IsLoaded)
                {
                    firstP.paperTypeReference.Load();
                }

                var shopPaperPrice = curShop.Shop_Paper_Price.FirstOrDefault(sp => sp.PaperTypeId == firstP.paperType.PaperTypeID);
                if (shopPaperPrice != null)
                {
                    UnitPrice = shopPaperPrice.UnitPrice;
                }
                else
                {
                    //UnitPrice = 0;
                    throw new Exception("产品纸型未定义价格");
                }
                Area = (oi.Width * oi.Height * 2.54 * 2.54) * oi.PageNum / 10000;//平方米
                Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Area * (double)UnitPrice;

                orderInfoPrice += Convert.ToDecimal(Count);


                bddList.Add(new Bill_Detail_Detail_Info()
                {
                    Area = Area,
                    Count = Count,
                    DetailName = firstP.paperType.Name + "数码输出",
                    Num = (int)Num,
                    Spec = oi.Width.ToString() + "*" + oi.Height.ToString(),
                    Type = (int)Bill_Detail_Detail_Type.NeedStatArea,
                    UnitPrice = (double)UnitPrice
                });

                return;

            }
            #endregion

            foreach (var ps in oi.photoInfo.GroupBy(p => p.paperType))
            {
                var shopPaperPrice = curShop.Shop_Paper_Price.FirstOrDefault(sp => sp.PaperTypeId == ps.Key.PaperTypeID);


                #region new
                foreach (var pSize in GetSizeInfo(ps.ToList()))
                {

                    isSuperOut = false;

                    if (shopPaperPrice != null)
                    {
                        UnitPrice = shopPaperPrice.UnitPrice;
                    }
                    else
                    {
                        UnitPrice = 0;
                    }

                    if (pSize.Width > 30 && pSize.Height > 30)
                    {
                        //超了  
                        isSuperOut = true;
                    }
                    else if (pSize.Width <= 30 && pSize.Height > 49)
                    {
                        //超了
                        isSuperOut = true;
                    }
                    else if (pSize.Height <= 30 && pSize.Width > 49)
                    {
                        //超了
                        isSuperOut = true;
                    }

                    if (isSuperOut && superOutPaperPrice == -1)
                    {
                        //从SystemSetting表中获取加费的的价格
                        //superOutPaperPrice = SystemSettingDAL.GetSuperOutPaperPrice();
                    }

                    if (isSuperOut)
                    {
                        UnitPrice += superOutPaperPrice;
                    }


                    double Count;
                    Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : pSize.Areas * (double)UnitPrice;
                    orderInfoPrice += Convert.ToDecimal(Count);
                    bddList.Add(new Bill_Detail_Detail_Info()
                    {
                        Area = Math.Round(pSize.Areas, 4),
                        Count = Count,
                        DetailName = ps.Key.Name + "数码输出",
                        Num = pSize.Num,
                        Spec = pSize.Spec,
                        Type = (int)Bill_Detail_Detail_Type.NeedStatArea,
                        UnitPrice = (double)UnitPrice
                    });
                }
                #endregion

            }
        }
        /// <summary>
        /// 添加面积收费类产品非直出
        /// </summary>
        /// <param name="orderInfoPrice"></param>
        /// <param name="oi"></param>
        /// <param name="curShop"></param>
        /// <param name="UnitPrice"></param>
        /// <param name="Num"></param>
        /// <param name="bddList"></param>
        private static void GetAreaPrice(ref decimal orderInfoPrice, orderInfo oi, Shop curShop, ref decimal UnitPrice, ref double Num, List<Bill_Detail_Detail> bddList, Shop_Product_Price spp)
        {
            //decimal superOutPaperPrice = -1;//超出尺寸的输出价格的加价是多少
            //bool isSuperOut = false;//是否超出尺寸

            foreach (var p in oi.photoInfo)
            {
                if (!p.paperTypeReference.IsLoaded)
                {
                    p.paperTypeReference.Load();
                }
            }

            #region //这种情况主要针对开单计算预估价格时产品是设计类的情况
            if (oi.PageNum > 0 && oi.photoInfo.Count > 0 && oi.photoInfo.Count > oi.PageNum && (oi.ProductType == (int)OrderInfoProductType.NeedDesignProduct || oi.ProductType == (int)OrderInfoProductType.NeedDesignPrint))//这种情况主要针对开单计算预估价格时产品是设计类的情况
            {
                //如果是这种情况就用如下的方式
                double Area = 0, Count;


                var shopPaperPrice = spp.UnitPrice;

                Area = (oi.Width * oi.Height * 2.54 * 2.54) * oi.PageNum / 10000;//平方米
                Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Area * (double)UnitPrice;

                orderInfoPrice += Convert.ToDecimal(Count);


                bddList.Add(new Bill_Detail_Detail()
                {
                    Area = Area,
                    Count = Count,
                    DetailName = spp.Tb_Product.ProductName,
                    Num = (int)Num,
                    Spec = oi.Width.ToString() + "*" + oi.Height.ToString(),
                    Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                    UnitPrice = (double)UnitPrice
                });

                return;

            }
            #endregion

            foreach (var ps in oi.photoInfo.GroupBy(p => p.paperType))
            {
                var shopPaperPrice = spp.UnitPrice;


                #region new
                foreach (var pSize in GetSizeInfo(ps.ToList()))
                {

                    //isSuperOut = false;

                    if (shopPaperPrice != null)
                    {
                        UnitPrice = shopPaperPrice;
                    }
                    else
                    {
                        UnitPrice = 0;
                    }




                    double Count;
                    Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : pSize.Areas * (double)UnitPrice;
                    orderInfoPrice += Convert.ToDecimal(Count);
                    bddList.Add(new Bill_Detail_Detail()
                    {
                        Area = Math.Round(pSize.Areas, 4),
                        Count = Count,
                        DetailName = spp.Tb_Product.ProductName,
                        Num = pSize.Num,
                        Spec = pSize.Spec,
                        Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                        UnitPrice = (double)UnitPrice
                    });
                }
                #endregion

            }
        }

        /// <summary>
        /// 添加面积收费类产品非直出
        /// </summary>
        /// <param name="orderInfoPrice"></param>
        /// <param name="oi"></param>
        /// <param name="curShop"></param>
        /// <param name="UnitPrice"></param>
        /// <param name="Num"></param>
        /// <param name="bddList"></param>
        private static void GetAreaPrice(ref decimal orderInfoPrice, orderInfo oi, Shop curShop, ref decimal UnitPrice, ref double Num, List<Bill_Detail_Detail_Info> bddList, Shop_Product_Price spp)
        {
            //decimal superOutPaperPrice = -1;//超出尺寸的输出价格的加价是多少
            //bool isSuperOut = false;//是否超出尺寸

            foreach (var p in oi.photoInfo)
            {
                if (!p.paperTypeReference.IsLoaded)
                {
                    p.paperTypeReference.Load();
                }
            }

            #region //这种情况主要针对开单计算预估价格时产品是设计类的情况
            if (oi.PageNum > 0 && oi.photoInfo.Count > 0 && oi.photoInfo.Count > oi.PageNum && (oi.ProductType == (int)OrderInfoProductType.NeedDesignProduct || oi.ProductType == (int)OrderInfoProductType.NeedDesignPrint))//这种情况主要针对开单计算预估价格时产品是设计类的情况
            {
                //如果是这种情况就用如下的方式
                double Area = 0, Count;


                var shopPaperPrice = spp.UnitPrice;

                Area = (oi.Width * oi.Height * 2.54 * 2.54) * oi.PageNum / 10000;//平方米
                Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : Area * (double)UnitPrice;

                orderInfoPrice += Convert.ToDecimal(Count);


                bddList.Add(new Bill_Detail_Detail_Info()
                {
                    Area = Area,
                    Count = Count,
                    DetailName = spp.Tb_Product.ProductName,
                    Num = (int)Num,
                    Spec = oi.Width.ToString() + "*" + oi.Height.ToString(),
                    Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                    UnitPrice = (double)UnitPrice
                });

                return;

            }
            #endregion

            foreach (var ps in oi.photoInfo.GroupBy(p => p.paperType))
            {
                var shopPaperPrice = spp.UnitPrice;


                #region new
                foreach (var pSize in GetSizeInfo(ps.ToList()))
                {

                    //isSuperOut = false;

                    if (shopPaperPrice != null)
                    {
                        UnitPrice = shopPaperPrice;
                    }
                    else
                    {
                        UnitPrice = 0;
                    }




                    double Count;
                    Count = (oi.OrderType == (int)OrderInfoType.OutReturnInfo) ? 0 : pSize.Areas * (double)UnitPrice;
                    orderInfoPrice += Convert.ToDecimal(Count);
                    bddList.Add(new Bill_Detail_Detail_Info()
                    {
                        Area = Math.Round(pSize.Areas, 4),
                        Count = Count,
                        DetailName = spp.Tb_Product.ProductName,
                        Num = pSize.Num,
                        Spec = pSize.Spec,
                        Type = (int)Bill_Detail_Detail_Type.UnNeedStatArea,
                        UnitPrice = (double)UnitPrice
                    });
                }
                #endregion

            }
        }

        /// <summary>
        /// 照片的尺寸、数据、面积
        /// </summary>
        class PhotoSizeAndAreaAndNum
        {
            public double Areas { get; set; }
            public int Num { get; set; }
            public double Width { get; set; }//单位英寸
            public double Height { get; set; }

            public string Spec { get { return Width.ToString("0.0") + "×" + Height.ToString("0.0") + " in" + "(" + (Width * 2.54).ToString("0.0") + "×" + (Height * 2.54).ToString("0.0") + " cm" + ")"; } }
        }
        /// <summary>
        ///  比较照片的尺寸
        /// </summary>
        class ComparePhotoSizeAndAreaAndNum : IEqualityComparer<PhotoSizeAndAreaAndNum>
        {

            #region IEqualityComparer<PhotoSizeAndAreaAndNum> 成员

            public bool Equals(PhotoSizeAndAreaAndNum x, PhotoSizeAndAreaAndNum y)
            {
                if (x == null || y == null)
                {
                    return false;
                }
                if ((x.Width == y.Width && x.Height == y.Height) || (x.Width == y.Height && x.Height == y.Width))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

            public int GetHashCode(PhotoSizeAndAreaAndNum obj)
            {
                return obj.ToString().GetHashCode();
            }

            #endregion
        }


        private static List<PhotoSizeAndAreaAndNum> GetSizeInfo(List<photoInfo> photos)
        {
            List<PhotoSizeAndAreaAndNum> rList = new List<PhotoSizeAndAreaAndNum>();
            ComparePhotoSizeAndAreaAndNum comp = new ComparePhotoSizeAndAreaAndNum();
            foreach (var pi in photos)
            {
                //PhotoSizeAndAreaAndNum pn = new PhotoSizeAndAreaAndNum() { Areas = pi.Width * pi.Height * 2.54 * 2.54 / 10000, Num = 1, Width = pi.Width, Height = pi.Height };

                PhotoSizeAndAreaAndNum find = rList.FirstOrDefault(p => (p.Height == pi.Height && p.Width == pi.Width) || (p.Height == pi.Width && p.Width == pi.Height));
                if (find != null)
                {
                    find.Num += pi.TotalNum ?? 1;
                    find.Areas += (pi.Width * pi.Height * 2.54 * 2.54 * pi.TotalNum ?? 1) / 10000;
                }
                else
                {
                    rList.Add(new PhotoSizeAndAreaAndNum() { Areas = (pi.Width * pi.Height * 2.54 * 2.54 * pi.TotalNum ?? 1) / 10000, Num = pi.TotalNum ?? 1, Width = pi.Width, Height = pi.Height });
                }
            }

            return rList;
        }
        /// <summary>
        /// 此商户上个自然月的帐是否结清
        /// </summary>
        /// <param name="shopId"></param>
        /// <returns>false:上个月还有帐未结清,true:已结清</returns>
        private static bool IsIndebtInLastMoth(int shopId, newSampleYPDBEntities db)
        {
            int unCheck = (int)ShopBillStatus.UnCheckOut;
            DateTime curTime = CommonMethodDAL.GetServerTime();
            DateTime lastMonth = Convert.ToDateTime(curTime.ToString("yyyy-MM-01")).AddMonths(-1);

            List<SHOP_Bill> listBill = db.SHOP_Bill.Where(sb => sb.Shop.ShopId == shopId && sb.Status == unCheck && lastMonth > sb.CreateTime).ToList();
            if (listBill.Count > 0)
            {
                return false;

            }
            else
            {
                return true;
            }
        }

        #endregion
    }
}
